/*
 * ESP8266语音控制小车
 * 通过WiFi接收语音指令控制小车前进/后退
 * 使用L298N电机驱动模块
 */

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

// WiFi配置
const char* ssid = "ESP8266_Car";
const char* password = "12345678";

// 电机控制引脚定义
const int motorA1 = D1;  // 左电机输入1
const int motorA2 = D2;  // 左电机输入2
const int motorB1 = D3;  // 右电机输入1
const int motorB2 = D4;  // 右电机输入2

// 创建Web服务器
ESP8266WebServer server(80);

// 当前状态
String currentState = "stop";

void setup() {
  Serial.begin(115200);
  
  // 设置电机引脚为输出
  pinMode(motorA1, OUTPUT);
  pinMode(motorA2, OUTPUT);
  pinMode(motorB1, OUTPUT);
  pinMode(motorB2, OUTPUT);
  
  // 初始化电机停止
  stopCar();
  
  // 设置WiFi为AP模式
  WiFi.softAP(ssid, password);
  Serial.println("WiFi AP已启动");
  Serial.print("IP地址: ");
  Serial.println(WiFi.softAPIP());
  
  // 设置Web服务器路由
  server.on("/", handleRoot);
  server.on("/forward", handleForward);
  server.on("/backward", handleBackward);
  server.on("/stop", handleStop);
  
  server.begin();
  Serial.println("HTTP服务器已启动");
}

void loop() {
  server.handleClient();
}

// 处理根路径请求
void handleRoot() {
  String html = "<!DOCTYPE html>"
                "<html>"
                "<head>"
                "<title>ESP8266语音控制小车</title>"
                "<meta name='viewport' content='width=device-width, initial-scale=1'>"
                "<style>"
                "body { font-family: Arial; text-align: center; margin: 50px; }"
                ".button { padding: 20px 40px; margin: 10px; font-size: 18px; cursor: pointer; }"
                ".forward { background: #4CAF50; color: white; }"
                ".backward { background: #f44336; color: white; }"
                ".stop { background: #ff9800; color: white; }"
                "#status { font-size: 24px; margin: 20px; }"
                "</style>"
                "</head>"
                "<body>"
                "<h1>ESP8266语音控制小车</h1>"
                "<div id='status'>当前状态: " + currentState + "</div>"
                "<button class='button forward' onclick='sendCommand(\"forward\")'>前进</button><br>"
                "<button class='button backward' onclick='sendCommand(\"backward\")'>后退</button><br>"
                "<button class='button stop' onclick='sendCommand(\"stop\")'>停止</button><br>"
                "<br><br>"
                "<button class='button' onclick='startVoiceControl()' style='background: #2196F3; color: white;'>开始语音控制</button>"
                "<script>"
                "function sendCommand(cmd) {"
                "  fetch('/' + cmd).then(() => location.reload());"
                "}"
                "function startVoiceControl() {"
                "  if ('webkitSpeechRecognition' in window) {"
                "    const recognition = new webkitSpeechRecognition();"
                "    recognition.lang = 'zh-CN';"
                "    recognition.onresult = function(event) {"
                "      const command = event.results[0][0].transcript;"
                "      if (command.includes('前进')) sendCommand('forward');"
                "      else if (command.includes('后退')) sendCommand('backward');"
                "      else if (command.includes('停止')) sendCommand('stop');"
                "    };"
                "    recognition.start();"
                "    alert('请说"前进"、"后退"或"停止"');"
                "  } else {"
                "    alert('您的浏览器不支持语音识别');"
                "  }"
                "}"
                "</script>"
                "</body>"
                "</html>";
  server.send(200, "text/html", html);
}

// 前进
void handleForward() {
  currentState = "forward";
  Serial.println("前进");
  digitalWrite(motorA1, HIGH);
  digitalWrite(motorA2, LOW);
  digitalWrite(motorB1, HIGH);
  digitalWrite(motorB2, LOW);
  server.send(200, "text/plain", "前进");
}

// 后退
void handleBackward() {
  currentState = "backward";
  Serial.println("后退");
  digitalWrite(motorA1, LOW);
  digitalWrite(motorA2, HIGH);
  digitalWrite(motorB1, LOW);
  digitalWrite(motorB2, HIGH);
  server.send(200, "text/plain", "后退");
}

// 停止
void handleStop() {
  currentState = "stop";
  Serial.println("停止");
  stopCar();
  server.send(200, "text/plain", "停止");
}

// 停止小车
void stopCar() {
  digitalWrite(motorA1, LOW);
  digitalWrite(motorA2, LOW);
  digitalWrite(motorB1, LOW);
  digitalWrite(motorB2, LOW);
}
